﻿using AutoMapper;
using PublishNews.Models;
using PublishNews.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using Microsoft.AspNet.Identity;

namespace PublishNews.Controllers
{
    public abstract class BaseApiController<T, TModel> : ApiController where T: Entities.Entity where TModel: BaseModel
    {
        public IRepository<T> Repository { get; set; }

        public BaseApiController(IRepository<T> repository)
        {
            Repository = repository;
        }

        public virtual IHttpActionResult Get()
        {
            var entities = Repository.DbSet().OrderByDescending(x => x.UpdatedDate).ThenByDescending(x => x.CreatedDate);
            var model = Mapper.Map<IEnumerable<TModel>>(entities);
            return Ok(model);
        }

        public virtual async Task<IHttpActionResult> GetBy(Guid id)
        {
            var entity = await Repository.GetBy(id);
            var model = Mapper.Map<TModel>(entity);

            if (model == null)
            {
                return NotFound();
            }

            return Ok(model);
        }

        [HttpPost]
        public virtual async Task<IHttpActionResult> Add(TModel model)
        {
            model.CreatedBy = User.Identity.GetUserName();
            model.CreatedDate = DateTime.Now;

            var entity = Mapper.Map<T>(model);

            try
            {
                await Repository.Add(entity);
            }
            catch (Exception e)
            {
                return InternalServerError(e);
            }

            return Ok(new {id = entity.Id});
        }

        [HttpPost]
        public virtual async Task<IHttpActionResult> Update(TModel model)
        {
            model.UpdatedBy = User.Identity.GetUserId();
            model.UpdatedDate = DateTime.Now;

            var oldEntity = await Repository.GetBy(model.Id);

            var entity = Mapper.Map<T>(model);

            entity.CreatedDate = oldEntity.CreatedDate;
            entity.CreatedBy = oldEntity.CreatedBy;

            try
            {
                await Repository.Update(entity);
            }
            catch (Exception e)
            {
                return InternalServerError(e);
            }

            return Ok();
        }

        [HttpPost]
        public virtual async Task<IHttpActionResult> Remove(TModel model)
        {
            try
            {
                await Repository.Remove(model.Id);
            }
            catch (Exception e)
            {
                return InternalServerError(e);
            }

            return Ok();
        }

        public IHttpActionResult Test()
        {
            return Ok();
        }
    }
}
